Next | Prev | Up | Top | Contents | Index

POWER Indigo2 and POWER CHALLENGE M Drivers

For POWER Indigo2 or POWER CHALLENGE M processors, uncached
(K1 segment) writes to main memory must be double-word (64-bit) writes, and they must be aligned on a double-word boundary. The reason for this has to do with the POWER Indigo2's hardware support for ECC-protected memory. Since the ECC calculation requires that data be written to main memory in 64-bit (8-byte) chunks, smaller (1-, 2-, and 4-byte) uncached writes to main memory tend to produce memory corruption. Cached accesses (both read and write), as well as uncached read operations do not cause problems; neither do accesses that are not to main memory, such as device register reads and writes.

Any device driver that performs uncached writes to main memory must always do writes in 8-byte quantities.[19] If the driver needs to write a smaller piece of memory, then it must do the write as a read-modify-write operation of an 8-byte piece of memory. For example, a driver with code like the following (assuming that the structure is being accessed uncached), would corrupt memory:

struct foo_s {
    char    b0;
    char    b1;
    char    b2;
    char    b3;
    char    b4;
    char    b5;
    char    b6;
    char    b7;
} bar1;

driver_write_bar1_b3 ()
{
    bar1.b3 = 5;
}
Instead, it would have to be modified to perform a read-modify-write operation on the whole double-word containing b3, as in the following example (on a big-endian system):

struct foo_s {
    union {
        __uint64    dw;    /* A 64-bit quantity */
        struct {
            char    b0;    /* READ ONLY */
            char    b1;    /* READ ONLY */
            char    b2;    /* READ ONLY */
            char    b3;    /* READ ONLY */
            char    b4;    /* READ ONLY */
            char    b5;    /* READ ONLY */
            char    b6;    /* READ ONLY */
            char    b7;    /* READ ONLY */
        } byte;
    } dw0;
} bar1;

driver_write_bar1_b3 ()
{
    bar1.dw0.dw = (bar1.dw0.dw & ~(0xff<<32)) | (5<<32);
}
If at all possible, use cached accesses to memory, along with cache coherency operations where necessary, instead of uncached operations. Cache coherency operations are necessary only for data shared by the CPU and a device that needs to perform DMA. See "Data Cache Write Back and Invalidation" for more information on use of cache coherency operations.


[19] Access to device registers does not fall under this restriction.
Sharing Data Between CPU and Peripheral Devices
Using mmap()

Next | Prev | Up | Top | Contents | Index